package com.cencat.merchant.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cencat.merchant.entity.DispatchRecordEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 派单记录数据访问层
 * 
 * @author cencat
 * @since 2024
 */
@Mapper
public interface DispatchRecordMapper extends BaseMapper<DispatchRecordEntity> {
    
    /**
     * 根据订单ID查询派单记录
     * 
     * @param orderId 订单ID
     * @return 派单记录列表
     */
    @Select("SELECT * FROM biz_dispatch_record WHERE order_id = #{orderId} AND deleted = 0 ORDER BY assign_time DESC")
    List<DispatchRecordEntity> selectByOrderId(@Param("orderId") Long orderId);
    
    /**
     * 根据司机ID查询派单记录
     * 
     * @param driverId 司机ID
     * @return 派单记录列表
     */
    @Select("SELECT * FROM biz_dispatch_record WHERE driver_id = #{driverId} AND deleted = 0 ORDER BY assign_time DESC")
    List<DispatchRecordEntity> selectByDriverId(@Param("driverId") Long driverId);
    
    /**
     * 根据派单状态查询记录
     * 
     * @param status 派单状态
     * @return 派单记录列表
     */
    @Select("SELECT * FROM biz_dispatch_record WHERE dispatch_status = #{status} AND deleted = 0 ORDER BY assign_time DESC")
    List<DispatchRecordEntity> selectByStatus(@Param("status") Integer status);
    
    /**
     * 查询待接单的派单记录
     * 
     * @param driverId 司机ID
     * @return 待接单记录列表
     */
    @Select("SELECT * FROM biz_dispatch_record WHERE driver_id = #{driverId} " +
            "AND dispatch_status = 0 AND deleted = 0 ORDER BY assign_time DESC")
    List<DispatchRecordEntity> selectPendingByDriverId(@Param("driverId") Long driverId);
    
    /**
     * 查询司机当前进行中的订单数量
     * 
     * @param driverId 司机ID
     * @return 进行中订单数量
     */
    @Select("SELECT COUNT(*) FROM biz_dispatch_record WHERE driver_id = #{driverId} " +
            "AND dispatch_status IN (0, 1) AND deleted = 0")
    Integer countActiveOrdersByDriverId(@Param("driverId") Long driverId);
    
    /**
     * 根据租户ID和时间范围查询派单记录
     * 
     * @param tenantId 租户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 派单记录列表
     */
    @Select("SELECT * FROM biz_dispatch_record WHERE tenant_id = #{tenantId} " +
            "AND assign_time >= #{startTime} AND assign_time <= #{endTime} " +
            "AND deleted = 0 ORDER BY assign_time DESC")
    List<DispatchRecordEntity> selectByTenantIdAndTimeRange(@Param("tenantId") Long tenantId,
                                                          @Param("startTime") LocalDateTime startTime,
                                                          @Param("endTime") LocalDateTime endTime);
    
    /**
     * 更新派单状态
     * 
     * @param recordId 记录ID
     * @param status 新状态
     * @return 更新行数
     */
    @Update("UPDATE biz_dispatch_record SET dispatch_status = #{status}, update_time = NOW() WHERE id = #{recordId}")
    int updateStatus(@Param("recordId") Long recordId, @Param("status") Integer status);
    
    /**
     * 更新司机响应时间
     * 
     * @param recordId 记录ID
     * @param responseTime 响应时间
     * @return 更新行数
     */
    @Update("UPDATE biz_dispatch_record SET response_time = #{responseTime}, update_time = NOW() WHERE id = #{recordId}")
    int updateResponseTime(@Param("recordId") Long recordId, @Param("responseTime") LocalDateTime responseTime);
    
    /**
     * 更新实际送达时间
     * 
     * @param recordId 记录ID
     * @param actualArrivalTime 实际送达时间
     * @return 更新行数
     */
    @Update("UPDATE biz_dispatch_record SET actual_arrival_time = #{actualArrivalTime}, update_time = NOW() WHERE id = #{recordId}")
    int updateActualArrivalTime(@Param("recordId") Long recordId, @Param("actualArrivalTime") LocalDateTime actualArrivalTime);
    
    /**
     * 设置拒绝原因
     * 
     * @param recordId 记录ID
     * @param rejectReason 拒绝原因
     * @return 更新行数
     */
    @Update("UPDATE biz_dispatch_record SET reject_reason = #{rejectReason}, " +
            "dispatch_status = 2, response_time = NOW(), update_time = NOW() WHERE id = #{recordId}")
    int updateRejectReason(@Param("recordId") Long recordId, @Param("rejectReason") String rejectReason);
    
    /**
     * 设置取消原因
     * 
     * @param recordId 记录ID
     * @param cancelReason 取消原因
     * @return 更新行数
     */
    @Update("UPDATE biz_dispatch_record SET cancel_reason = #{cancelReason}, " +
            "dispatch_status = 3, update_time = NOW() WHERE id = #{recordId}")
    int updateCancelReason(@Param("recordId") Long recordId, @Param("cancelReason") String cancelReason);
    
    /**
     * 根据算法类型统计派单数量
     * 
     * @param tenantId 租户ID
     * @param algorithmType 算法类型
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 派单数量
     */
    @Select("SELECT COUNT(*) FROM biz_dispatch_record WHERE tenant_id = #{tenantId} " +
            "AND algorithm_type = #{algorithmType} " +
            "AND assign_time >= #{startTime} AND assign_time <= #{endTime} " +
            "AND deleted = 0")
    Long countByAlgorithmType(@Param("tenantId") Long tenantId,
                             @Param("algorithmType") Integer algorithmType,
                             @Param("startTime") LocalDateTime startTime,
                             @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计派单成功率
     * 
     * @param tenantId 租户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 成功派单数量
     */
    @Select("SELECT COUNT(*) FROM biz_dispatch_record WHERE tenant_id = #{tenantId} " +
            "AND dispatch_status IN (1, 4) " +
            "AND assign_time >= #{startTime} AND assign_time <= #{endTime} " +
            "AND deleted = 0")
    Long countSuccessfulDispatches(@Param("tenantId") Long tenantId,
                                  @Param("startTime") LocalDateTime startTime,
                                  @Param("endTime") LocalDateTime endTime);
    
    /**
     * 查询超时未接单的派单记录
     * 
     * @param timeoutMinutes 超时分钟数
     * @return 超时记录列表
     */
    @Select("SELECT * FROM biz_dispatch_record WHERE dispatch_status = 0 " +
            "AND assign_time <= DATE_SUB(NOW(), INTERVAL #{timeoutMinutes} MINUTE) " +
            "AND deleted = 0")
    List<DispatchRecordEntity> selectTimeoutRecords(@Param("timeoutMinutes") Integer timeoutMinutes);
    
    /**
     * 查询平均响应时间
     * 
     * @param tenantId 租户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 平均响应时间(秒)
     */
    @Select("SELECT AVG(TIMESTAMPDIFF(SECOND, assign_time, response_time)) " +
            "FROM biz_dispatch_record WHERE tenant_id = #{tenantId} " +
            "AND response_time IS NOT NULL " +
            "AND assign_time >= #{startTime} AND assign_time <= #{endTime} " +
            "AND deleted = 0")
    Double getAverageResponseTime(@Param("tenantId") Long tenantId,
                                 @Param("startTime") LocalDateTime startTime,
                                 @Param("endTime") LocalDateTime endTime);
}